<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <link href="/layui/lib/css/layui.css" rel="stylesheet" type="text/css" />
    <script src="/layui/lib/layui.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/Sortable/1.15.2/Sortable.min.js"></script>
    <style class="text/css">
        #leftNav{
            border: 1px solid #ccc;
            min-height: 600px;
        }

        #designArea{
            border: 1px solid #ccc;
            margin-left: 8px;
            min-height: 600px;
        }

        .ctrlItem{
            min-width: 60px;
            min-height: 20px;
        }

        .ctrlItemInfo{
            border: 1px solid #000;
        }

        .canPut{

        }

        .canPull{

        }

        .minHeight{

        }

        .ctrlItemOver{
            border: 1px solid #000;
        }

    </style>
</head>
<body>


    <blockquote class="layui-elem-quote">sortable.js调试</blockquote>
    

<div class="layui-row">
    <div class="layui-col-md1 " id="leftNav">
        <button class="ctrl ctrlButton">按钮</button>
        <button class="ctrl ctrlDiv">容器</button>
        <button class="ctrl ctrlLayuiRow">Layui行</button>
    </div>
    <div class="layui-col-md11">
        
        <div class="layui-row">设计区</div>
        <div id="designArea" class="ctrlItem" ctrl-type="form">

            <div class="layui-row ctrlItem ctrlItemInfo">abc</div>

            <div class="ctrlItem">
                <button>add</button>
                <button>modify</button>
            </div>
           
        </div>
        <div>
            <div class="layui-row">
                <textarea class="layui-textarea" id="ctrlDefine">

                </textarea>
            </div>
            <div class="layui-row"><button class="layui-btn" id="btnSaveCtrlDefine">保存定义</button></div>
        </div>


    </div>
</div>


    <script>
        var util = {
            getHtmlAttr : function(attrMap){
                var strInfo = "";
                $.each(attrMap,function(i,item){
                    strInfo += item.key +"=\"" + item.value + "\" ";
                });

                if(strInfo !== ""){
                    strInfo = strInfo.substr(0, strInfo.length - 1);
                }

                return strInfo;
            },
            getAttr : function(){
                
            }
        }


        var ctrlMaxId = 0;

        var stdCtrlList =[
            {
                ctrlName:"按钮",
                ctrlType:"button"
            },
            {
                ctrlName:"容器",
                ctrlType:"div"
            },
            {
                ctrlName:"layui行",
                ctrlType:"layuiRow"
            },

        ];

        var ayCtrl = {

            ctrlDefine:[
                {
                    ctrlType:"button",
                    id:"",
                    class:"",
                    events:[],
                    caption:"按钮"
                },
                {
                    ctrlType:"div",
                    id:"",
                    class:"",
                    events:[]
                },
                {
                    ctrlType:"form",
                    id:"",
                    class:"",
                    events:[]
                },
                {
                    ctrlType:"layuiInput",
                    id:"",
                    class:"",
                    events:[]
                },
                {
                    ctrlType:"layuiRow",
                    id:"",
                    class:"",
                    events:[]
                },
                {
                    ctrlType:"layuiRowCol",
                    id:"",
                    class:"",
                    events:[]
                },
                {
                    ctrlType:"layuiTabItem",
                    id:"",
                    class:"",
                    events:[]
                },
            ],
            getCtrlDefine:function(type){

                var entity ;
                $.each(ayCtrl.ctrlDefine,function(i,item){
                    if(item.ctrlType === type){
                        entity = $.extend({},item);
                        return false;
                    }
                });

                return entity;
            },
            getNewCtrlId : function(){
                ctrlMaxId++;
                return "el" + ctrlMaxId;
            },
            //根据类型得到通用的属性
            // 这里还有子属性，比如字体，颜色 等属性还有
            getCommonHtmlAttr: function(define){
                if(typeof(define) === "undefined"){
                    return "";
                }

                var attrInfo = "";
                

                var classInfo="";
                if(define.hasOwnProperty("class")){
                    classInfo = define.class;
                    if(classInfo.length > 0){
                        classInfo +=" ctrlItem";
                    }
                    else{
                        classInfo = "ctrlItem";
                    }

                    var canPutList = "div, layuiRow, layuiRowCol, layuiTabItem,";
                    if(canPutList.indexOf(define.ctrlType+",") > -1){
                        classInfo +=" canPut"
                    }
                }

                if(classInfo.length > 0){
                    classInfo = "class=\"" + classInfo + "\"";
                }

                // classInfo 独立处理

                // 其他属性处理
                var htmlAttrList = "id,class,name,lay-filter,"
                for(var key in define){
                    if(key !== "class" && typeof(define[key]) !=="object"){
                        if(htmlAttrList.indexOf(key+",") > -1){
                            attrInfo += key+"=\"" + define[key] + "\" ";
                        }
                    }
                }

                attrInfo +=" " + classInfo;
                

                return attrInfo;

            },
            renderCtrl:function(define){
                console.log("define",define);

                var html = "";

                console.log("define",define);

                if(typeof(define) == "undefined"){
                    console.log("不存在当前的控件类型");
                    return "";
                }

                var ctrlType = define.ctrlType;
                console.log("ctrlType",ctrlType);

                if(ctrlType === "ctrlButton"){
                    html = ayCtrl.getButton(define);
                    return html;
                }

                if(ctrlType === "ctrlDiv"){
                    html = ayCtrl.getDiv(define);
                    return html;
                }
                
                if(ctrlType === "ctrlLayuiRow"){
                    html = ayCtrl.getLayuiRow(define);
                    return html;
                }

                if(ctrlType === "ctrlLayuiRowCol"){
                    html = ayCtrl.getLayuiRowCol(define);
                    return html;
                }

                if(ctrlType === "ctrlLayuiTab"){
                    html = ayCtrl.getLayuiTab(define);
                    return html;
                }

                if(ctrlType === "ctrlLayuiInput"){
                    html = ayCtrl.getLayuiInput(define);
                    return html;
                }

            },
            getButton:function(config){
                var attrInfo = ayCtrl.getCommonHtmlAttr(config);
                console.log("getButton attrInfo",attrInfo)

                var caption = config.caption;
                if(typeof(caption) === "undefined"){
                    caption = "按钮";
                }

                var html = "<button "+attrInfo+" adf-ctrl=\"button\">"+caption+"</button>";
                return html;
            },
            getDiv:function(config){
                var attrInfo = ayCtrl.getCommonHtmlAttr(config);
                var html = "<div "+attrInfo+" adf-ctrl=\"div\"></div>";
                return html;
            },
            getLayuiRow:function(config){
                var attrInfo = ayCtrl.getCommonHtmlAttr(config);
                var html = "<div "+attrInfo+" adf-ctrl=\"layuiRow\"></div>";
                return html;
            },
            getLayuiRowCol:function(config){
                var ctrlId = ayCtrl.getNewCtrlId();
                var html = "<div id=\""+ctrlId+"\" class='layui-col-md6 canPut ctrlItem'></div>";
                return html;
            },
            getLayuiInput:function(config){
                var ctrlId = ayCtrl.getNewCtrlId();
                var html = "<input id=\""+ctrlId+"\" class='layui-input ctrlItem' />";
                return html;
            },
            getLayuiTab:function(config){
                var ctrlId = ayCtrl.getNewCtrlId();
                var pre = "<div class=\"layui-tab ctrlItem\" id=\""+ctrlId+"\">";
                var tabtitle = "<ul class=\"layui-tab-title\"><li class=\"layui-this\">选项1</li></ul>";
                var tabContent = "<div class=\"layui-tab-content\"><div class=\"layui-tab-item layui-show ctrlItem canPut\"></div></div>"
                var suffix = "</div>"
                var html = pre + tabtitle + tabContent + suffix;
                return html;
            }
            

        };
    
    var ayForm = {

        CtrlList:[],
        formStruct:{id:"designArea",ctrlType:"form",childs:[]},
        // 返回对象以及当前的路径
        getCtrlObjectById : function(id){
            //通过递归的方式换到控件json对象
            function doFind(obj,targetId){
                for (var key in obj) {
                    console.log("key",key);
                    if (key === "id") {
                        if (obj.id === targetId) {
                            return obj;
                        }
                    }

                    if (typeof obj[key] === "object" && obj[key] !== null) {
                            var result = doFind(obj[key], targetId);
                            if (result) {
                                return result;
                            }
                    }
                }
                return null;
            }
            console.log("ayForm.formStruct",ayForm.formStruct);
            var obj = doFind(ayForm.formStruct,id);
            console.log("find obj",obj);
            return obj;
        },
        //开始初始化
        init:function(){
            // 初始化左侧
            new Sortable(document.getElementById('leftNav'), {
                group: {
                    name: 'shared', // 组名
                    pull: "clone",     // 允许拖出元素
                    put: false       // 允许放入元素
                },
                sort:false,
                animation: 150,

            }); 

            this.initLefNavCtrl();
            this.initDesignSortable();
            this.initCtrlSort();
            this.initEvent();

        },

        initLefNavCtrl:function(){
            $("#leftNav").html("");
            $(stdCtrlList).each(function(i,item){
                var button = "<button class=\"ctrl "+item.ctrlType+"\" ctrl-type=\""+item.ctrlType+"\">"+item.ctrlName+"</button>";
                $("#leftNav").append(button);
            });
        },

        initEvent:function(){

            //
            $("body").on("mouseover",".ctrlItem",function(){
                $(this).addClass("ctrlItemOver")
            })

            $("body").on("mouseout",".ctrlItem",function(){
                $(this).removeClass("ctrlItemOver")
            })

            //保存控件定义

            $("body").on("click","#btnSaveCtrlDefine",function(){
                var config = JSON.parse($("#ctrlDefine").val());
                var html = ayCtrl.renderCtrl(config);
                console.log("html",html);
                var ctrlId = config.id;
                //插入新的html 同时将自身给移除掉
                $("#"+ctrlId).after(html).remove();
            })
        },
        putEl:function(to,from,dragEl,event){
            console.log("to",to);
            console.log("from",from);
            console.log("dragEl",dragEl);

            //判断是否可以放入什么样的新元素
            if($(from.el).attr("id") === "leftNav"){
                //表示来源于左侧
                //var curCtrl = $(dragEl).hasClass("ctrlButton")

                if(!($(to.el).hasClass("canPut"))){
                    console.log("无移入类，则不能移入");
                    return false;
                }
            } 

            if($(from.el).hasClass("ctrlItem")){
                //
                if(!($(to.el).hasClass("canPut"))){
                    console.log("无移入类，则不能移入");
                    return false;
                }
            }


            console.log("看有没有执行...");
            return true;
        },
        pullEl:function(to,from,dragEl,event){
            console.log("to",to);
            console.log("from",from);
            console.log("dragEl",dragEl);

            var classInfo = $(dragEl).attr("class");
            if(classInfo.indexOf("layui-col-md")){
                return false;
            }


            return true;
        },
        addEl:function(evt){

            //在设计的元素在各个容器中互相拖动的
            if($(evt.from).attr("id") === "leftNav"){
                console.log("从左侧菜单中入设计区");
                ayForm.addElFromLeftNav(evt);
            } 
            else{
                if($(evt.from).hasClass("ctrlItem")){
                    console.log("设计区控件之间互相移入");
                    ayForm.addElFromDesign(evt);
                }
            }

            //对新增加的元素赋值新的移动属性
            ayForm.initCtrlSort();
            return false;

        },
        addElFromDesign(evt){
           console.log("addElFromDesign",evt);
        },
        addElFromLeftNav:function(evt){

            //这里需要完成的事情,得到控件的配置文件
            //这里是完成控件增加操作，使用的是默认，不涉及控件的参数调整

            console.log("addElFromLeftNav",evt);
            var dragItem = evt.item;
            
            var targetContainer = evt.to;
            var targetId = $(targetContainer).attr("id");
            console.log("targetId",targetId);
            var targetObj = ayForm.getCtrlObjectById(targetId);
            console.log("targetObj",targetObj);
            if(typeof(targetObj) === "undefined"){
                layer.msg("父级容器不存在");
                return;
            }
            var targetCtrlType = targetObj.ctrlType;
            console.log("targetCtrlType",targetCtrlType);
            
            //原始先移除掉
            var ctrlType = $(dragItem).attr("ctrl-type");
            $(dragItem).remove();

            //将新的html进行解析
            var newHtml = "";

            //得到类型
            var define = ayCtrl.getCtrlDefine(ctrlType);

            if(typeof(define) === "undefined" || define.ctrlType === ""){
                layer.msg("不存在当前控件");
                return "";
            }

            var newHtml = "";
            if(ctrlType === "button"){
                define.id = ayCtrl.getNewCtrlId();
                newHtml = ayCtrl.getButton(define);
            }
            if(ctrlType === "div"){
                define.id = ayCtrl.getNewCtrlId();
                newHtml = ayCtrl.getDiv(define);
            }
            if(ctrlType === "layuiRow"){
                define.id = ayCtrl.getNewCtrlId();
                define.class = "layui-row";
                newHtml = ayCtrl.getLayuiRow(define);
            }

            //增加json中
            var childsParent = "form,div,layuiRow,";
            if(childsParent.indexOf(targetCtrlType+",") > -1){
                targetObj.childs.push(define);
            }

            var itemParent = "tab,"
            if(itemParent.indexOf(targetCtrlType+",") > -1){
                targetObj.items.push(define);
            }

            console.log("newHtml",newHtml);
            if(newHtml !== ""){
                $(targetContainer).append(newHtml);
            }

            console.log("targetObj",targetObj);
            console.log("ayForm.formStruct",JSON.stringify(ayForm.formStruct));
            $("#ctrlDefine").val(JSON.stringify(ayForm.formStruct));
            
            return "";

        },
        initCtrlSort:function(){
            var ctrlList = document.getElementsByClassName('ctrlItem');
            console.log("ctrlList",ctrlList);

             // 遍历每个容器并初始化 Sortable
             Array.from(ctrlList).forEach(container => {
                new Sortable(container, {
                    group: {
                            name: 'shared', // 组名
                            pull: function(to,from,dragEl,event){
                                return ayForm.pullEl(to,from,dragEl,event);
                            },     
                            // 允许拖出元素
                            put: function(to,from,dragEl){
                                return ayForm.putEl(to,from,dragEl);
                            }
                        },
                        draggable:".ctrlItem",
                        animation: 150,
                        sort:true,
                        forcePlaceholderSize: true,
                        onAdd:function(evt){
                            ayForm.addEl(evt);
                        }
                });
            });

        },
        //初始化设计区排序值
        initDesignSortable:function(){
            //初始化排序
            // 初始化右侧
            new Sortable(document.getElementById('designArea'), {
                        group: {
                            name: 'shared', // 组名
                            pull: true,     // 允许拖出元素
                            put: true       // 允许放入元素
                        },
                        animation: 150,
                        draggable:".ctrlItem",
                        sort:true,
                        forcePlaceholderSize: true,
                        onAdd:function(evt){
                            ayForm.addEl(evt);
                        }
                    }); 


        }

    }

    ayForm.init();

    </script>
</body>
</html>